Skip to content

Open Harness Server subcommands - #1853

Open
SSharma-10 wants to merge 81 commits into
mainfrom
feat/agents-subcommands
Open

Open Harness Server subcommands#1853
SSharma-10 wants to merge 81 commits into
mainfrom
feat/agents-subcommands

Conversation

@SSharma-10

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread commands/agents.go
Comment thread commands/agents.go Outdated

@logwolvy logwolvy left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming, relevant godo changes for sending agent spec yaml are done.
Please address the comments and we should be good to merge.

Comment thread commands/agents.go Outdated
Comment thread commands/agents.go Outdated
Comment thread commands/agents.go Outdated
SSharma-10 and others added 6 commits June 3, 2026 16:52
doctl agent attach connected but printed nothing: the harness-api SSE
stream emits the SPI canonical event envelope (type/data/timestamp/
tenant_id, dot-separated event names) while vendored godo decoded
kind/payload/at/team_id, so every event fell through renderEvent.

- godo HostedAgentEvent: decode the SPI wire via UnmarshalJSON and switch
  the HostedAgentEventKind constants to the dot-separated SPI names.
- godo ErrorResponse: also read the nested {"error":{code,message}}
  envelope so failed calls show the server's reason, not a bare status.
- agents: align event payload structs/rendering and HITL tracking to the
  SPI data shapes, and acknowledge each submit with its run id so the
  agent's startup latency isn't mistaken for a hang (which caused
  duplicate submits).
- tests for the wire decode, rendering, nested-error surfacing, and ack.

The vendored godo edits mirror the fix being upstreamed to
digitalocean/godo and are in-tree until godo is re-vendored.

Co-authored-by: Cursor <cursoragent@cursor.com>
logwolvy
logwolvy previously approved these changes Jun 8, 2026

@logwolvy logwolvy left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will be raising a PR for stream related fixes on doctl and godo.

Comment thread internal/deviceid/deviceid_darwin.go
Comment thread internal/deviceid/deviceid_windows.go
Comment thread commands/agents_test.go
@@ -0,0 +1,1215 @@
/*
Copyright 2026 The Doctl Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apple Pay

Vendors glamour and its transitive deps (chroma, goldmark, bluemonday,
etc.) and bumps lipgloss/termenv so `doctl agents` can render the
agent's markdown replies with syntax-highlighted code blocks. Also
re-syncs the pinned godo vendor tree (adds Session.SandboxID).

Co-authored-by: Cursor <cursoragent@cursor.com>
julia-ye and others added 12 commits July 28, 2026 12:44
Bump godo to the build that points StreamSession at the data plane's
`/v2/agents/sessions/{id}/events`, and handle what the new endpoint adds.

`agents logs` is unaffected: godo keeps replay-only reads on the control
plane's `/stream`, which is the only side holding the stored history.

The live stream carries `stream.state` transport control frames reporting
connection health. They are not session activity, so they never render and
never become the reconnect cursor. One of them needs acting on:
`superseded` means another connection from this device took the session
over, and it is the one stream end we must not reconnect from — re-attaching
would take it back, and the two windows would evict each other indefinitely.

Also drop the "one connected device per session" claim from `start-proxy`'s
help. Distinct devices now coexist; what actually conflicts is running the
proxy and `attach` from the same machine, since both stream as this device.

Test changes: the reconnect test reads the resume cursor from Last-Event-ID
instead of a replay_from query parameter, and the agentproxy harness serves
`/events` and opens every stream with a `stream.state` frame, so the codex
facade tests exercise a stream shaped like the real one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The godo bump in the previous commit updated go.mod/go.sum but not
vendor/, so `go test -mod=vendor` (what CI runs) failed with
"inconsistent vendoring": go.mod required the new pseudo-version while
vendor/modules.txt still declared v1.201.0-beta.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bumps godo to pick up the replay-only move onto
`/v2/agents/sessions/{id}/events?replay_only=true`. `doctl agents logs` was
the last reader still pointed at the control plane's `/stream`; it now shares
the data-plane endpoint with `doctl agents attach`.

No change to how events are parsed or rendered -- the endpoint emits the same
canonical envelope, and the stream still ends after the last stored event,
which is what lets the command exit.

The help text no longer promises the *full* history. The data plane serves
history out of the durable event log rather than the control plane's
database, so it is bounded by retention and by a per-read cap; a long-idle or
unusually long session may replay only its more recent activity.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
julia-ye and others added 10 commits July 31, 2026 13:11
…story. Update handleConn to trigger AfterReply after successful JSON-RPC replies. Adjust Dispatch method to call AfterReply when a request is successful. Enhance replay logic to prevent race conditions with thread/start and thread/resume replies.
…ered after successful JSON-RPC replies in handleConn. This change aligns with the contract of AfterReply and improves the handling of replay sessions.
)

* MARSOHS-867 fix JSON output contract violations on triggers create, rotate-secret, get-execution, and list endpoints

- create / rotate-secret: route the webhook-secret banner and URL to
  stderr (not stdout) when -o json is active; rotate-secret now also
  emits {"webhook_secret":"..."} to stdout so programmatic callers
  receive machine-readable output (MARSOHS-867)

- get-execution: suppress the run-output text block from stdout when
  -o json; the structured JSON object already carries the data
  (MARSOHS-868)

- list displayers (HostedAgentTrigger, HostedAgentTriggerExecution,
  HostedAgentWebhookProvider, HostedAgentReusableSession): remove the
  len==1 special-case that returned a bare object instead of a
  one-element array; list endpoints always return an array regardless
  of row count (MARSOHS-869)

Co-authored-by: Cursor <cursoragent@cursor.com>

* MARSOHS-867 fix get-verb JSON shape: restore bare-object output for single-item responses

The previous commit removed the len==1 unwrap from all displayer JSON()
methods to fix list returning a bare object for one row (MARSOHS-869).
That was too broad: get/create/update/pause/resume/get-by-session/
get-execution all return one object and must emit bare JSON, not an array.

Add Single bool to HostedAgentTrigger and HostedAgentTriggerExecution.
When Single=true JSON() unwraps the slice to a bare object (get/mutate
semantics); when false (default) it always emits an array (list semantics).

Single=true:  create, get, update, pause, resume, get-by-session,
              get-execution
Single=false: list, list-executions, list-providers,
              list-reusable-sessions

Co-authored-by: Cursor <cursoragent@cursor.com>

* MARSOHS-867 add tests covering JSON output contract for triggers verbs

Displayer shape tests (commands/displayers/agent_triggers_test.go):
  - list with 0/1/2 items always emits a JSON array (MARSOHS-869)
  - get-execution / get with Single=true emits a bare JSON object

Command-level routing tests (commands/agent_triggers_test.go):
  - create -o json: stdout is valid JSON; banner not on stdout (MARSOHS-867)
  - rotate-secret -o json: stdout is {"webhook_secret":"..."} (MARSOHS-867)
  - rotate-secret text: banner still on stdout (regression guard)
  - get-execution -o json: stdout is valid JSON from byte 0 (MARSOHS-868)
  - get-execution text: OutputText still printed (regression guard)

Co-authored-by: Cursor <cursoragent@cursor.com>

* MARSOHS-867 fix same JSON list-shape bug in HostedAgentSession displayer

agents list -o json returned a bare object when exactly one session
existed, same root cause as MARSOHS-869 on triggers. Apply the same
Single bool pattern: list caller (RunAgentsList) keeps Single=false so
output is always an array; get/create callers (RunAgentsGet,
RunAgentsCreate) set Single=true for bare-object responses.

No stdout-before-Display issue found in agents commands - the
nextPageToken in RunAgentsList already routes to os.Stderr in JSON mode.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants